package com.ly.system.service.sysuser.Impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ly.common.core.constants.HttpConstants;
import com.ly.common.core.domain.LoginUser;
import com.ly.common.core.domain.R;
import com.ly.common.core.domain.vo.LoginUserVO;
import com.ly.common.core.enums.ResultCode;
import com.ly.common.core.enums.UserIdentity;
import com.ly.common.security.exception.ServiceException;
import com.ly.common.security.service.TokenService;
import com.ly.system.domain.sysuser.dto.LoginDTO;
import com.ly.system.domain.sysuser.SysUser;
import com.ly.system.mapper.sysuser.SysUserMapper;
import com.ly.system.service.sysuser.ISysUserService;
import com.ly.system.utils.BCryptUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
//不需要重启服务即可生效
@RefreshScope
//实现了 ISysUserService 接口，并提供了 login 方法的具体实现
public class SysUserServiceImpl implements ISysUserService  {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private TokenService tokenService;

    @Value("${jwt.secret}")
    private String secret;

    @Override
    public R<String> login(String userAccount, String password){
//        int a=10/0;

        //通过账号去数据库中查询,对应的用户信息
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        //select password from tb_sys_sur where user_account=#{userAccount}
        //SysUser::getUserAccount 是对 SysUser 类的 getUserAccount 方法的方法引用

        SysUser sysUser=sysUserMapper.selectOne(queryWrapper
                .select(SysUser::getUserId,SysUser::getPassword,SysUser::getNickName)
                .eq(SysUser::getUserAccount,userAccount));
//        R<Void> loginResult=new R<Void>();
        if(sysUser==null){
//            在common R中调用
//             loginResult.setCode(ResultCode.FAILED_USER_NOT_EXISTS.getCode());
//             loginResult.setMsg(ResultCode.FAILED_USER_NOT_EXISTS.getMsg());
//             return loginResult;
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        if(BCryptUtils.matchesPassword(password,sysUser.getPassword())){
//            loginResult.setCode(ResultCode.SUCCESS.getCode());
//            loginResult.setMsg(ResultCode.SUCCESS.getMsg());
//            return loginResult;
            //jwttoken = 生产jwttoken的方法
            return R.ok(tokenService.createToken(sysUser.getUserId(),
                    secret, UserIdentity.ADMIN.getValue(),sysUser.getNickName(),null));
        }
//        loginResult.setCode(ResultCode.FAILED_LOGIN.getCode());
//        loginResult.setMsg(ResultCode.FAILED_LOGIN.getMsg());
//        return loginResult;
        return R.fail(ResultCode.FAILED_LOGIN);
    }

    @Override
    public int add(LoginDTO.SysUserSaveDTO sysUserSaveDTO) {
        //重复代码
        //将dto转为实体
        List<SysUser> sysUserList= sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserAccount,sysUserSaveDTO.getUserAccount()));
        //isNotEmpty 不为空返回true,返回true说明有数据
        if(CollectionUtil.isNotEmpty(sysUserList)){
            //用户已经存在
            //自定义异常 公共的异常类
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }
        SysUser sysUser=new SysUser();
        sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        sysUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));

        //父类也需要赋值(也就是公共字段,基本都会使用到,可以提出来)(MyBaitsPlus提供的一个方法)
//        sysUser.setCreateBy(100L);//创建人 获取当前用户id 如何获取当前调用接口的id
//        sysUser.setCreateTime(LocalDateTime.now());//创建时间
//        sysUser.setUpdateBy(100L);//更新时间

        return sysUserMapper.insert(sysUser);
    }

    @Override
    public boolean logout(String token) {

        //检查token是否为空
        if (StrUtil.isEmpty(token)) {
            throw new IllegalArgumentException("Token cannot be null or empty");
        }
        //再处理前缀
        if (token.startsWith(HttpConstants.PREFIX)) {
            token = token.substring(HttpConstants.PREFIX.length());
        }

       return tokenService.deleteLoginUser(token,secret);

    }

    @Override
    public R<LoginUserVO> info(String token) {

//        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
//            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
//        }

        // 先检查token是否为空
        if (StrUtil.isEmpty(token)) {
            throw new IllegalArgumentException("Token cannot be null or empty");
        }
//      再处理前缀
        if (token.startsWith(HttpConstants.PREFIX)) {
            token = token.substring(HttpConstants.PREFIX.length());
        }

        LoginUser loginUser = tokenService.getLoginUser(token, secret);


        if(loginUser==null){
            return R.fail();
        }
        LoginUserVO loginUserVO=new LoginUserVO();
        loginUserVO.setNickName(loginUser.getNickName());
        return R.ok(loginUserVO);
    }



//    public int add(SysUserSaveDTO sysUserSaveDTO){
//        List<SysUser> sysUserList=sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
//                .equals(SysUser::getUserAccount,sysUserSaveDTO.getUserAccount()));
//        if (CollectionUtils.isN)
//    }
//    编译时异常
//    运行时异常
//    全局异常处理  日志框架
//    1.增加全局异常处理
//    2.当捕获到异常时,记录相关的日志,作为问题排查的线索
}
